package smtp;

import java.awt.Color;
import java.io.FileNotFoundException;

import javax.mail.MessagingException;
import javax.swing.JList;
import javax.swing.ListSelectionModel;

import smtp.EmailListCellRenderer;

import com.sun.mail.imap.IMAPFolder;

/**
 * A JList of IMAPMessages whose arrangement is modeled in the MessageListModel
 * IMAPMessages exist in the same IMAPFolder
 * 
 * Paints the IMAP messages as describes in the EmailListCellRenderer
 * 
 * Originally, the check boxes next to each message were intended to select a set
 * of messages for deletion or similar operation.  Problems were encountered in
 * setting the behavior of a checkbox within a JList cell.  UI-intense and not a priority.
 * 
 * @author chandlerr, liw, wendlandts
 *
 */
public class JMessageList extends JList {
	MessageListModel model;
	EmailListCellRenderer cellRenderer;
	IMAPFolder folder;


	/**
	 * Constructor
	 * @param f - IMAPFolder with messages (or lack of messages) to view
	 */
	public JMessageList (IMAPFolder f){
		super();
		folder = f;
		folder.getName(); // ensures the folder's name is saved in object cache

		// set a MessageListModel and an EmailListCellRenderer as the model and renderer
		setModelandRenderer();

		setPrototypeCellValue("No Data");
		setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		setBackground(new Color(206,242,255).brighter());
	}	

	/**
	 * Create a new MessageListModel and EmailListCellRenderer to represent a new folder
	 * But first close the old folder.
	 * @param f - new folder
	 */
	public void changeFolder(IMAPFolder f){
		closeCurrentFolder();
		folder = f;
		clearSelection();
		setModelandRenderer();
	}

	/**
	 * Close current folder
	 */
	private void closeCurrentFolder(){
		// Try a regular close
		if(folder.isOpen()){
			try {
				folder.close(false);
			} catch (MessagingException e) {
				System.out.println("Unable to close folder.");
				e.printStackTrace();
			}
		}

		// Wait 4 seconds
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			System.out.println("Thread interrupted exception.");
			e.printStackTrace();
		}

		// Try a forced close
		if(folder.isOpen()){
			System.out.println("Unable to close folder " + folder.getName() + ".\n" +
			"Attempting forced close...");
			try {
				folder.forceClose();
			} catch (MessagingException e) {
				System.out.println("Unable to perform forced close on folder.  Program exiting.");
				e.printStackTrace();
				System.exit(1);
			}
		}
	}

	/**
	 * Set up a new MessageListModel and EmailListCellRenderer for the folder
	 */
	private void setModelandRenderer(){
		try {
			model = new MessageListModel(folder);
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (MessagingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		cellRenderer = new EmailListCellRenderer();

		model.addListDataListener(cellRenderer.getDataListener());

		setModel(model);
		setCellRenderer(cellRenderer);
	}
	
	/**
	 * Move the view to the next page as described in MessageListModel
	 * 
	 * @return - whether  a next page exists after the operation is performed 
	 * @throws MessagingException
	 */
	public boolean next() throws MessagingException{
		// selection needs to be cleared or it will be invalid
		this.clearSelection();
		return model.next();
	}
	
	/**
	 * Move the view to the previous page as described in MessageListModel
	 * 
	 * @return - whether  a previous page exists after the operation is performed 
	 * @throws MessagingException
	 */
	public boolean prev() throws MessagingException{
		// selection needs to be cleared or it will be invalid
		this.clearSelection();
		return model.prev();
	}
	
	/**
	 * @return - whether a next page exists as described in MessageListModel
	 */
	public boolean hasNext(){
		return model.hasNext();
	}
	
	/**
	 * @return - whether a previous page exists as described in MessageListModel
	 */
	public boolean hasPrev(){
		return model.hasPrev();
	}

}
